package failover

import (
	"context"
	"gitee.com/DonHz/basic-go/webook/internal/service/sms"
	"sync/atomic"
)

type TimeoutFailoverSMSService struct {
	svcs []sms.Service
	idx int32
	// 连续超时的个数
	cnt int32

	// 阈值
	threshold int32
}

func NewTimeoutFailoverSMSService(svcs []sms.Service, idx int32, cnt int32, threshold int32) sms.Service {
	return &TimeoutFailoverSMSService{
		svcs: svcs,
		idx: idx,
		cnt: cnt,
		threshold: threshold,
	}
}

func (t TimeoutFailoverSMSService) Send(ctx context.Context, tpl string, args []string, numbers ...string) error {
	idx:=atomic.LoadInt32(&t.idx)
	cnt:=atomic.LoadInt32(&t.cnt)
	if cnt>t.threshold {
		// 切换
		newIdx:=(idx+1)%int32(len(t.svcs))
		// 原子操作，并发安全
		if atomic.CompareAndSwapInt32(&t.idx, idx, newIdx) {
			atomic.StoreInt32(&t.cnt, 0)
		}
		// else 出现并发，别人换成功了
		idx = atomic.LoadInt32(&t.idx)
	}
	svc:=t.svcs[idx]
	err:=svc.Send(ctx, tpl, args, numbers...)
	switch err {
	case context.DeadlineExceeded:
		// 超时
		atomic.AddInt32(&t.cnt, 1)
	case nil:
		// 发送成功
		atomic.StoreInt32(&t.cnt, 0)
	default:
		// 不知道什么错误
		// 超时，直接下一个
		// 非超时，再试试，或者直接换下一个
	}
	return err
}


